package cn.szsys.integration.billrule.strtegy;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Ryan
 * @date 2025-05-13
 **/
@Component
@Slf4j
@SuppressWarnings("all")
public class DelaySaveRecordHandler implements InitializingBean {
    @Resource
    private Map<String, AbstractDelaySaveRecord> delaySaveRecordMap;

    private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;


    @Override
    public void afterPropertiesSet() {
        scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1, r -> getCustomerThread(r));
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(this::run, 1000, 500, TimeUnit.MILLISECONDS);
    }

    /**
     * 获取线程
     *
     * @param runnable runnable
     * @return java.lang.Thread
     * @author rhf
     */
    Thread getCustomerThread(Runnable runnable) {
        ThreadGroup tg = Thread.currentThread().getThreadGroup();
        for (ThreadGroup tgn = tg;
             tgn != null;
             tg = tgn, tgn = tg.getParent()) {
            Thread thread = new CustomerThread(tg, runnable);
            thread.setPriority(Thread.MIN_PRIORITY);
            thread.setDaemon(true);
            return thread;
        }
        return null;
    }

    public void run() {
        for (String beanName : delaySaveRecordMap.keySet()) {
            AbstractDelaySaveRecord abstractDelaySaveRecord = delaySaveRecordMap.get(beanName);
            int size = abstractDelaySaveRecord.getSize();
            //如果队列没数据,表示这段时间没有请求,直接返回
            if (size == 0) {
                continue;
            }
            List list = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                // 后面的SQL语句是有长度限制的，所以还要做限制每次批量的数量,超过最大任务数，等下次执行
                if (i < abstractDelaySaveRecord.getTaskBatchSize()) {
                    list.add(abstractDelaySaveRecord.getTask());
                }else{
                    break;
                }
            }
            try {
                abstractDelaySaveRecord.scheduleTask(list);
            } catch (Exception e) {
                log.error("beanName:[{}],调用延迟保存方法错误:", beanName, e);
            }
        }
    }

    private static class CustomerThread extends Thread {
        CustomerThread(ThreadGroup g, Runnable runnable) {
            super(g, runnable, "thread-delaySaveRecordHandler");
        }
    }
}

